package eu.news.index;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.util.Version;
import org.wltea.analyzer.lucene.IKAnalyzer;
import org.wltea.analyzer.lucene.IKQueryParser;
import org.wltea.analyzer.lucene.IKSimilarity;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;

import eu.jk.helper.RootPath;
import eu.news.data.hibernate.pojo.HB_News;

public class NewsIndexDAO {
	static IndexWriter writer=null;
	static Directory dir=null;
	
	static {
		Analyzer analyzer = new IKAnalyzer();
		IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_32,analyzer);
		try {
			dir=FSDirectory.open(new File(RootPath.root+"../indexes/news/"));
			writer = new IndexWriter(dir, config);
		} catch (CorruptIndexException e) {
			e.printStackTrace();
		} catch (LockObtainFailedException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static void updateIndex(HB_News news){
		if(news==null)
			return;
		deleteIndex(news);
		Document doc = new Document();
		Field id=new Field("id", String.valueOf(news.getId()), Store.YES, Index.NOT_ANALYZED);
		Field content=new Field("content", 
				news.getTitle()+" "+news.getContent(), 
				Store.NO, Index.ANALYZED);
		Field sort=new Field("sort", news.getSort().getName(),Store.NO,Index.NOT_ANALYZED);
		Field special=new Field("special",news.getSort().getSpecial().getName(),
				Store.NO,Index.NOT_ANALYZED);
		doc.add(content);
		doc.add(id);
		doc.add(sort);
		doc.add(special);
		try {
			writer.addDocument(doc);
			writer.commit();
		} catch (CorruptIndexException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static Collection<Integer> search(String str){
		return search(str, 20);
	}
	
	public static Collection<Integer> search(String str,int maxMatch){
		try {
			IndexSearcher searcher=new IndexSearcher(dir);
			searcher.setSimilarity(new IKSimilarity());
			Query query=IKQueryParser.parse("content", str);
			TopDocs docs=null;
			docs = searcher.search(query, maxMatch);
			Document doc = null;
			List<Integer> news=new ArrayList<Integer>(20);
			for(ScoreDoc did:docs.scoreDocs){
				doc=searcher.doc(did.doc);
				news.add(Integer.parseInt(doc.get("id")));
			}
			return news;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public static Collection<Integer> search(String keyword,String sortName,
			String specialName,int maxMatch){
		try {
			IndexSearcher searcher=new IndexSearcher(dir);
			searcher.setSimilarity(new IKSimilarity());
			BooleanQuery query=new BooleanQuery();
			if(keyword!=null)
				query.add(IKQueryParser.parse("content", keyword), BooleanClause.Occur.MUST);
			if(sortName!=null)
				query.add(new TermQuery(new Term("sort",sortName)), BooleanClause.Occur.MUST);
			if(specialName!=null)
				query.add(new TermQuery(new Term("special", specialName)), BooleanClause.Occur.MUST);
			TopDocs docs=null;
			docs = searcher.search(query, maxMatch);
			Document doc = null;
			List<Integer> news=new ArrayList<Integer>(20);
			for(ScoreDoc did:docs.scoreDocs){
				doc=searcher.doc(did.doc);
				news.add(Integer.parseInt(doc.get("id")));
			}
			return news;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public static void deleteIndex(HB_News news){
		if(news==null)
			return;
		try {
			Query query=new TermQuery(new Term("id", String.valueOf(news.getId())));
			writer.deleteDocuments(query);
			writer.commit();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void close(){
		try {
			writer.close();
		} catch (CorruptIndexException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
